import React, { useState, useRef, useMemo } from 'react'
import { assign, map, find } from 'lodash'
import { useClickAway } from 'ahooks'
import { observer, inject } from 'mobx-react'

import VideoPlayer from '../common/video-player'
import MenuItem from './menu-item'
import useSubs from '../../hooks/useSubs'
import { getBoundingClientRect } from '../../util/index'
import videoStore from '../../store/video'
import common from '../../store/common'
import ScreenShot from './screen-shot'
import './styles/right-menu.scss'

const RightMenu = () => {
  const { event$ } = common
  const { curScreenId, mode } = videoStore

  const [visible, setVisible] = useState(false)
  const [data, setData] = useState({ pos: { x: '', y: '' }, screen: {} })
  const [pos, setPos] = useState({ left: 0, top: 0 })
  const [disable, setDisable] = useState(false)
  const [videoStatus, setVideoStatus] = useState('play')
  const [itemList, setItemList] = useState(getItemList(videoStatus, mode))
  const [oneScreen, setOneScreen] = useState(false)

  const ref = useRef()
  const videoPlayerRef = useRef()

  useSubs(({ action, val }) => {
    if (action === 'showRightMenu') {
      setVisible(true)
      setData(val)
    }
  })

  useClickAway(() => {
    setVisible(false)
  }, ref)

  useMemo(() => {
    if (visible) {
      const { left: vleft, top: vtop } = getBoundingClientRect('video')
      const { pos, screenId } = data
      const { x, y } = pos
      const left = x - vleft
      const top = y - vtop
      const screen = videoStore.findScreenById(screenId)
      screen?.player ? setDisable(false) : setDisable(true)
      setPos({ left, top })
      setVideoStatus(screen?.status)
    }
  }, [data])

  useMemo(() => {
    for (const item of itemList) {
      item.disable = disable
    }
  }, [disable])

  useMemo(() => {
    setItemList(getItemList(videoStatus, mode))
  }, [videoStatus, mode])

  function getItemList(videoStatus, mode) {
    return [
      {
        label: setStatusLabel('退出单屏', '单屏', mode === 1),
        disable: false,
        borderBottom: true,
        clickMenu: showOneScreen,
      },
      {
        label: '视频信息',
        disable,
        borderBottom: true,
        clickMenu: showVideoInfo,
      },
      {
        label: setStatusLabel('暂停播放', '开始播放', videoStatus === 'pause'),
        disable,
        clickMenu: playOrPause,
      },
      {
        label: '全部播放',
        disable,
        clickMenu: playAll,
      },
      {
        label: '全部暂停',
        disable,
        borderBottom: true,
        clickMenu: pauseAll,
      },
      {
        label: '关闭视频',
        disable,
        clickMenu: stopVideo,
      },
      {
        label: '关闭全部视频',
        disable,
        borderBottom: true,
        clickMenu: stopAllVideo,
      },
      {
        label: '截图',
        disable,
        clickMenu: shot,
      },
      {
        label: '截取全部播放',
        disable,
        clickMenu: shotAll,
      },
    ]
  }

  function showOneScreen() {
    videoStore.setMode(!oneScreen ? 1 : videoStore.lastMode)
    setOneScreen(!oneScreen)
  }

  function setStatusLabel(str1, str2, val) {
    return val ? str1 : str2
  }

  function showVideoInfo() {
    event$.emit({ action: 'showVideoInfo', val: data.screenId })
  }

  function playOrPause() {
    const { playVideo, pauseVideo } = videoPlayerRef.current
    if (videoStatus === 'play') {
      playVideo(curScreenId)
      setVideoStatus('pause')
    } else {
      pauseVideo(curScreenId)
      setVideoStatus('play')
    }
  }

  function playAll() {
    for (const { id } of videoStore.playingScreens) {
      videoPlayerRef.current.playVideo(id)
      setVideoStatus('pause')
    }
  }

  function pauseAll() {
    for (const { id } of videoStore.playingScreens) {
      videoPlayerRef.current.pauseVideo(id)
      setVideoStatus('play')
    }
  }

  function stopVideo() {
    videoPlayerRef.current.stopVideo()
  }

  function stopAllVideo() {
    for (const { id } of videoStore.playingScreens) {
      videoPlayerRef.current.stopVideo(id)
    }
  }

  function shot() {
    event$.emit({ action: 'screenShot', val: 'shot' })
  }

  function shotAll() {
    event$.emit({ action: 'screenShot', val: 'shotAll' })
  }

  return (
    <div>
      <div
        style={assign({ display: visible ? 'block' : 'none' }, pos)}
        className="menu-wrap"
        ref={ref}
        onClick={() => setVisible(false)}
      >
        {map(itemList, ({ label, disable, borderBottom, clickMenu }, k) => {
          return <MenuItem label={label} disable={disable} borderBottom={borderBottom} clickMenu={clickMenu} key={k} />
        })}
      </div>
      <VideoPlayer ref={videoPlayerRef} />
      <ScreenShot />
    </div>
  )
}

export default inject('store')(observer(RightMenu))
